{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.1 Vectors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Vectors in Julia are represented by one-dimensional Array objects. A vector is constructed by giving the list of elements surrounded by square brackets, with the elmeents separated by commas or semicolons. The assignment operator = is used to give a name to the array. The ```length``` function returns the size (dimension)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.1\n",
       "  0.0\n",
       "  3.9\n",
       " -7.2"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [-1.1, 0.0, 3.9, -7.2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "length(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.1\n",
       "  0.0\n",
       "  3.6\n",
       " -7.2"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = [-1.1; 0.0; 3.6; -7.2] #Using semicolons"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "length(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ```Array{Float64,1}``` displayed by Julia above each array tells us that the array is one-dimensional and its entries are floating point numbers that use 64 bits.\n",
    "\n",
    "**Some common mistakes.** Don't forget the commas or semicolons between entries, and be sure to use square brackets and not parentheses. Otherwise you'll get things that make sense in Julia, but are not vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 2)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [ 1 2 ]\n",
    "b = ( 1, 2 )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here ```a``` is a row vector, which we will encounter later; ```b``` is a tuple or list consisting of two scalars. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Indexing.**  A specific element $x_i$ is retrieved by the expression ```x[i]``` where ```i``` is the index (which runs to 1 to $n$, for an $n$-vector). Array indexing can also be used on the left-hand side of an assignment, to change the value of a specific element. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.6"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [ -1.1, 0.0, 3.6, -7.2 ];\n",
    "x[3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.1\n",
       "  0.0\n",
       "  4.0\n",
       " -7.2"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[3] = 4.0\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The special index ```end``` refers to the last index of a vector. In the example above, ```x[end]``` and ```x[length(x)]``` both give the last entry ```-7.2```.\n",
    "\n",
    "**Assignment versus copying**. Matlab or Octave users may be surprised by the behavior of an assignment ```y = x``` if ```x``` is an array. This expression gives a new name (or reference) ```y``` to the *same* array already referenced by ```x```. It does not create a new copy of the array ```x```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.1\n",
       "  0.0\n",
       "  4.0\n",
       " -7.2"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [ -1.1, 0.0, 3.6, -7.2 ];\n",
    "y = x\n",
    "x[3] = 4.0\n",
    "y #The assignment to x[3] also changes y[3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       "  2.0\n",
       "  0.0\n",
       "  4.0\n",
       " -7.2"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[1] = 2.0\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To create a new copy of an array, the function ```copy``` should be used."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.1\n",
       "  0.0\n",
       "  3.6\n",
       " -7.2"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [ -1.1, 0.0, 3.6, -7.2 ];\n",
    "y = copy(x)\n",
    "x[3] = 4.0\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.1\n",
       "  0.0\n",
       "  4.0\n",
       " -7.2"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[1] = 2.0\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Vector equality.** Equality of vectors is checked using the relational operator ```==```. For two vectors (arrays) ```a``` and ```b```, the Julia expression ```a==b``` evaluates to ```true``` if the vectors (arrays) are equal, *i.e.*, they have the same length and identical entries, and ```false``` otherwise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "false"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [ -1.1, 0.0, 3.6, -7.2 ];\n",
    "y = copy(x)\n",
    "y[3] = 4.0\n",
    "y == x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = x\n",
    "z[3] = 4.0\n",
    "z == x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Scalars versus 1-vectors.** In the mathematical notation used in VMLS we consider a 1-vector to be the same as a number. But in Julia, 1-vectors are not the same as scalars (numbers). Julia distinguishes between the 1-vector (array) ```[ 1.3 ]``` and the number ```1.3```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{Float64,1}:\n",
       " 1.3"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [1.3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.3"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = 1.3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "false"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x == y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[1] == y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the last line, ```x[1]``` is the first (and only) entry of ```x```, which is indeed the number ```1.3```.\n",
    "\n",
    "**Block or stacked vectors.** To construct a block vector in Julia, you can use ```vcat``` (vertical concatenate) or the semicolon (;) operator. Let's construct the block vector $z = (x,y)$ with $x = (1,-2)$ and $y = (1,1,0)$ using the two methods."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5-element Array{Int64,1}:\n",
       "  1\n",
       " -2\n",
       "  1\n",
       "  1\n",
       "  0"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [ 1,-2]; y = [1,1,0];\n",
    "z = [x; y] # Concatenate using semicolon"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5-element Array{Int64,1}:\n",
       "  1\n",
       " -2\n",
       "  1\n",
       "  1\n",
       "  0"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z = vcat(x,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As in mathematical notation, you can stack vectors with scalars, *e.g.*, ```[1;x;0]``` create (1,x,0).\n",
    "\n",
    "**Some common mistakes.** There are a few Julia operations that look similar but do not construct a block or stacked vector. For example, ```z = (x,y)``` creates a list or tuple of the two vectors; ```z = [x,y]``` creates an array of the two vectors. Both of these are valid Julia expressions, but neither of them is the stacked vector ```[x;y]```.\n",
    "\n",
    "**Subvectors and slicing.** As in the mathematical notation used in VMLS, the Julia expression ```r:s``` denotes the idnex range $r, r + 1,...,s$. (It is assumed here that ```r``` and ```s``` are positive integers with ```r``` the smaller of the two.) In VMLS we use $x_{r:s}$ to denote the slice of the vector x from index r to s. In Julia you can extract a subvector or slice of a vector using an index range as the argument. You can also use index ranges to assign a slice of a vector."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Int64,1}:\n",
       " 4\n",
       " 3\n",
       " 0"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [9,4,3,0,5]\n",
    "y = x[2:4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5-element Array{Int64,1}:\n",
       "  9\n",
       "  4\n",
       "  3\n",
       " -2\n",
       " -3"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[4:5] = [-2, -3]; #Re-assign the 4 and 5 entries of x\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Julia indexing into arrays.** Julia slicing and subjectoring is much more general than the mathematical notation we use in VMLS. For example, one can use a number range with a third argument, that gives the stride, which is the increment between successive indexes. For example, the index range ```1:2:5``` is the list of numbers ```1,3,5```. The expressiong ```x[1:2:5]``` extracts the 3-vector ```[9,3,5```, i.e., the first, third, and fifth entries of x defined above. You can also use an index range that runs backward. For any vector ```z```, the Julia expressiong ```z[end:-1:1]``` is the reversed vector, i.e., the vector with the same coefficients, but in opposite order. \n",
    "\n",
    "**Vector of first differences.** Let's use slicing to create the (n-1)-vector d defined by $d_i = x_{i+1} - x_i$ for $i = 1,...,n - 1$, where x is an n-vector. The vector d is called the vector of (first) differences of x."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Int64,1}:\n",
       " -1\n",
       "  0\n",
       " -2\n",
       "  4"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [1,0,0,-2,2];\n",
    "d = x[2:end] - x[1:end-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**List of vectors.** An ordered list of n-vectors might be denoted in VMLS as $a_1,...,a_k$ or $a^{(1)},...,a^{(k)}$ or just as $a,b,c$. There are several ways to represent lists of vectors in Julia. If we give the elements of the list, separated by commas, and surrounded by square brackets, we form a one-dimensional array of vectors. If instead we use parentheses as delimiters, we obtain a tuple, or list. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Array{Float64,1},1}:\n",
       " [1.0, 0.0] \n",
       " [1.0, -1.0]\n",
       " [0.0, 1.0] "
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [1.0, 0]; y = [1.0,-1.0]; z = [0,1.0];\n",
    "list = [x,y,z]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       "  1.0\n",
       " -1.0"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list[2] #Second element of list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1.0, 0.0], [1.0, -1.0], [0.0, 1.0])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list = (x,y,z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       " 0.0\n",
       " 1.0"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list[3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note the difference between ```[x,y,z]``` (an array of arrays) and ```[x;y;z]``` (an array of numbers, obtained by concatenation). To extract the ith vector from the list of vectors, use ```list[i]```. To get the jth element or coefficient of the ith vector in the list, use ```list[i][j]```.\n",
    "\n",
    "**Zero vectors**. In Julia a zero vector of dimension n is created using ```zeros(n)```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       " 0.0\n",
       " 0.0\n",
       " 0.0"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zeros(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The expression ```zeros(length(a))``` creates a vector with the same size as the vector ```a```.\n",
    "\n",
    "**Unit vectors**. There is no built-in Julia function for creating $e_i$, the ith unit vector of length n. THe following code creates $e_i$, with i = 2 and n = 4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " 0.0\n",
       " 1.0\n",
       " 0.0\n",
       " 0.0"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "i = 2; n = 4;\n",
    "ei = zeros(n); #Create a zero vector\n",
    "ei[i] = 1; #Set ith entry to 1\n",
    "ei"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's another way to create $e_i$ using concatenation, using a Julia inline function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "unit_vector (generic function with 1 method)"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "unit_vector(i,n) = [zeros(i-1); 1; zeros(n-i)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " 0.0\n",
       " 1.0\n",
       " 0.0\n",
       " 0.0"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "unit_vector(2,4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Ones vector.** In Julia, the ones vector of dimension n, denoted $\\textbf1_n$ or just $\\textbf1$ in VMLS, is created using ```ones(n)```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       " 1.0\n",
       " 1.0"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ones(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Random vectors.** We do not use or refer to random vectors in VMLS, which does not assume a background in probability. However, it is sometimes useful to generate random vectors, for example to test an identity or some algorithm. In Julia, ```rand(n)``` generates a random vector of length n with entries that are between 0 and 1. Each time this function is called or evaluated, it gives a different vector. The variant ```randn(n)``` (with the extra 'n' for normal) gives an n-vector with entries that come from a normal (Gaussian) distribution. They can be positive or negative, with typical values on the order of one. Remember that every time you evaluate these functions, you get a different random vector. In particular, you will obtain different entries in the vectors below when you run the code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       " 0.6050290514712375\n",
       " 0.2268306073512003"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rand(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       " 0.5376534648995441\n",
       " 0.9880951020978539"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rand(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Plotting**. There are several external packages for creating plots in Julia. One such package is Plots.jl, which you must add (install) via Julia's package manager control system; see page ix. Assuming the Plots package has been installed, you import it into Julia for use, using the command ```using Plots```. (This can take some time.) After that you can access the Julia commands that create or manipulate plots. \n",
    "\n",
    "For example, we can plot the temperature time series in Figure 1.3 of VMLS using the code below; the last line saves the plot in a file ```temperature.pdf```. The result is shown in Figure 1.1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "using Plots #Only need to do this once per session"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "temps = [71, 71, 68, 69, 68, 69,68, 74, 77, 82, 85, 86, 88, 86, 85, 86, 84, 79, 77, 75, 73, 71, 70, 70, 69, 69, 69, 69, 67, 68, 68, 73, 76, 77, 82, 84, 84, 81, 80, 78, 79, 78, 73, 72, 70, 70, 68, 67];"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"600\" height=\"400\" viewBox=\"0 0 2400 1600\">\n",
       "<defs>\n",
       "  <clipPath id=\"clip9200\">\n",
       "    <rect x=\"0\" y=\"0\" width=\"2400\" height=\"1600\"/>\n",
       "  </clipPath>\n",
       "</defs>\n",
       "<polygon clip-path=\"url(#clip9200)\" points=\"\n",
       "0,1600 2400,1600 2400,0 0,0 \n",
       "  \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
       "<defs>\n",
       "  <clipPath id=\"clip9201\">\n",
       "    <rect x=\"480\" y=\"0\" width=\"1681\" height=\"1600\"/>\n",
       "  </clipPath>\n",
       "</defs>\n",
       "<polygon clip-path=\"url(#clip9200)\" points=\"\n",
       "140.517,1487.47 2352.76,1487.47 2352.76,47.2441 140.517,47.2441 \n",
       "  \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
       "<defs>\n",
       "  <clipPath id=\"clip9202\">\n",
       "    <rect x=\"140\" y=\"47\" width=\"2213\" height=\"1441\"/>\n",
       "  </clipPath>\n",
       "</defs>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  140.517,1487.47 2352.76,1487.47 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  140.517,1487.47 140.517,47.2441 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  158.723,1487.47 158.723,1465.87 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  602.769,1487.47 602.769,1465.87 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  1046.82,1487.47 1046.82,1465.87 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  1490.86,1487.47 1490.86,1465.87 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  1934.91,1487.47 1934.91,1465.87 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  140.517,1252.61 173.7,1252.61 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  140.517,929.11 173.7,929.11 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  140.517,605.608 173.7,605.608 \n",
       "  \"/>\n",
       "<polyline clip-path=\"url(#clip9200)\" style=\"stroke:#000000; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  140.517,282.107 173.7,282.107 \n",
       "  \"/>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:middle;\" transform=\"rotate(0, 158.723, 1541.47)\" x=\"158.723\" y=\"1541.47\">0</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:middle;\" transform=\"rotate(0, 602.769, 1541.47)\" x=\"602.769\" y=\"1541.47\">10</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:middle;\" transform=\"rotate(0, 1046.82, 1541.47)\" x=\"1046.82\" y=\"1541.47\">20</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:middle;\" transform=\"rotate(0, 1490.86, 1541.47)\" x=\"1490.86\" y=\"1541.47\">30</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:middle;\" transform=\"rotate(0, 1934.91, 1541.47)\" x=\"1934.91\" y=\"1541.47\">40</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:end;\" transform=\"rotate(0, 116.517, 1270.11)\" x=\"116.517\" y=\"1270.11\">70</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:end;\" transform=\"rotate(0, 116.517, 946.61)\" x=\"116.517\" y=\"946.61\">75</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:end;\" transform=\"rotate(0, 116.517, 623.108)\" x=\"116.517\" y=\"623.108\">80</text>\n",
       "</g>\n",
       "<g clip-path=\"url(#clip9200)\">\n",
       "<text style=\"fill:#000000; fill-opacity:1; font-family:Arial,Helvetica Neue,Helvetica,sans-serif; font-size:48px; text-anchor:end;\" transform=\"rotate(0, 116.517, 299.607)\" x=\"116.517\" y=\"299.607\">85</text>\n",
       "</g>\n",
       "<polyline clip-path=\"url(#clip9202)\" style=\"stroke:#009af9; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
       "  203.127,1187.91 247.532,1187.91 291.937,1382.01 336.341,1317.31 380.746,1382.01 425.151,1317.31 469.555,1382.01 513.96,993.811 558.364,799.71 602.769,476.208 \n",
       "  647.174,282.107 691.578,217.406 735.983,88.0053 780.388,217.406 824.792,282.107 869.197,217.406 913.602,346.807 958.006,670.309 1002.41,799.71 1046.82,929.11 \n",
       "  1091.22,1058.51 1135.62,1187.91 1180.03,1252.61 1224.43,1252.61 1268.84,1317.31 1313.24,1317.31 1357.65,1317.31 1402.05,1317.31 1446.46,1446.71 1490.86,1382.01 \n",
       "  1535.27,1382.01 1579.67,1058.51 1624.08,864.41 1668.48,799.71 1712.89,476.208 1757.29,346.807 1801.69,346.807 1846.1,540.908 1890.5,605.608 1934.91,735.009 \n",
       "  1979.31,670.309 2023.72,735.009 2068.12,1058.51 2112.53,1123.21 2156.93,1252.61 2201.34,1252.61 2245.74,1382.01 2290.15,1446.71 \n",
       "  \"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"203.127\" cy=\"1187.91\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"203.127\" cy=\"1187.91\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"247.532\" cy=\"1187.91\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"247.532\" cy=\"1187.91\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"291.937\" cy=\"1382.01\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"291.937\" cy=\"1382.01\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"336.341\" cy=\"1317.31\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"336.341\" cy=\"1317.31\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"380.746\" cy=\"1382.01\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"380.746\" cy=\"1382.01\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"425.151\" cy=\"1317.31\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"425.151\" cy=\"1317.31\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"469.555\" cy=\"1382.01\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"469.555\" cy=\"1382.01\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"513.96\" cy=\"993.811\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"513.96\" cy=\"993.811\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"558.364\" cy=\"799.71\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"558.364\" cy=\"799.71\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"602.769\" cy=\"476.208\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"602.769\" cy=\"476.208\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"647.174\" cy=\"282.107\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"647.174\" cy=\"282.107\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"691.578\" cy=\"217.406\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"691.578\" cy=\"217.406\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"735.983\" cy=\"88.0053\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"735.983\" cy=\"88.0053\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"780.388\" cy=\"217.406\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"780.388\" cy=\"217.406\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"824.792\" cy=\"282.107\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"824.792\" cy=\"282.107\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"869.197\" cy=\"217.406\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"869.197\" cy=\"217.406\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"913.602\" cy=\"346.807\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"913.602\" cy=\"346.807\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"958.006\" cy=\"670.309\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"958.006\" cy=\"670.309\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1002.41\" cy=\"799.71\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1002.41\" cy=\"799.71\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1046.82\" cy=\"929.11\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1046.82\" cy=\"929.11\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1091.22\" cy=\"1058.51\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1091.22\" cy=\"1058.51\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1135.62\" cy=\"1187.91\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1135.62\" cy=\"1187.91\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1180.03\" cy=\"1252.61\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1180.03\" cy=\"1252.61\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1224.43\" cy=\"1252.61\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1224.43\" cy=\"1252.61\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1268.84\" cy=\"1317.31\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1268.84\" cy=\"1317.31\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1313.24\" cy=\"1317.31\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1313.24\" cy=\"1317.31\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1357.65\" cy=\"1317.31\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1357.65\" cy=\"1317.31\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1402.05\" cy=\"1317.31\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1402.05\" cy=\"1317.31\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1446.46\" cy=\"1446.71\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1446.46\" cy=\"1446.71\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1490.86\" cy=\"1382.01\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1490.86\" cy=\"1382.01\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1535.27\" cy=\"1382.01\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1535.27\" cy=\"1382.01\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1579.67\" cy=\"1058.51\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1579.67\" cy=\"1058.51\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1624.08\" cy=\"864.41\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1624.08\" cy=\"864.41\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1668.48\" cy=\"799.71\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1668.48\" cy=\"799.71\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1712.89\" cy=\"476.208\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1712.89\" cy=\"476.208\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1757.29\" cy=\"346.807\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1757.29\" cy=\"346.807\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1801.69\" cy=\"346.807\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1801.69\" cy=\"346.807\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1846.1\" cy=\"540.908\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1846.1\" cy=\"540.908\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1890.5\" cy=\"605.608\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1890.5\" cy=\"605.608\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1934.91\" cy=\"735.009\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1934.91\" cy=\"735.009\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"1979.31\" cy=\"670.309\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1979.31\" cy=\"670.309\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"2023.72\" cy=\"735.009\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"2023.72\" cy=\"735.009\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"2068.12\" cy=\"1058.51\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"2068.12\" cy=\"1058.51\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"2112.53\" cy=\"1123.21\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"2112.53\" cy=\"1123.21\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"2156.93\" cy=\"1252.61\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"2156.93\" cy=\"1252.61\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"2201.34\" cy=\"1252.61\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"2201.34\" cy=\"1252.61\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"2245.74\" cy=\"1382.01\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"2245.74\" cy=\"1382.01\" r=\"14\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#000000; stroke:none; fill-opacity:1\" cx=\"2290.15\" cy=\"1446.71\" r=\"18\"/>\n",
       "<circle clip-path=\"url(#clip9202)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"2290.15\" cy=\"1446.71\" r=\"14\"/>\n",
       "</svg>\n"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "plot(temps, marker = :circle, legend = false, grid = false)\n",
    "# savefig(\"temperature.pdf\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Figure 1.1** Hourly temperature in downtown Los Angeles on August 5 and 6, 2015 (starting at 12:47AM, ending at 11:47PM)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.2 Vector addition"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Vector addition and subtraction.** If ```x``` and ```y``` are vectors of the same size, ```x+y``` and ```x-y``` give their sum and difference, respectively."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Int64,1}:\n",
       " 1\n",
       " 9\n",
       " 3"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[0, 7, 3] + [1, 2, 0] #Vector addition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Int64,1}:\n",
       " 0\n",
       " 8"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[1,9] - [1,1] #Vector subtraction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.3 Scalar-vector multiplication"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Scalar-vector multiplication and division.** If ```a``` is a number and ```x``` a vector, you can express the scalar-vector product either as ```a*x``` or ```x*a```. (Julia actually allows you to write ```2.0x``` for ```2.0*x```. This is unambiguous because variable names cannot start with a number.) You can carry out scalar-vector division in a similar way, as ```x/a```, or the less familiar looking expression ```a\\x```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([0.0, 4.4, -2.2], [0.0, 4.4, -2.2])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [0, 2, -1]\n",
    "2.2*x, x*2.2 #Scalar-vector multiplication"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([0.0, 0.666667, -0.333333], [0.0, 0.666667, -0.333333])"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x/3, 3\\x #Scalar-vector division"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Scalar-vector addition.** In Julia you can add a scalar ```a``` and a vector ```x``` using ```x .+ a```. The dot that precedes the plus symbol tells Julia to apply the operation to each element. (More on this below.) The meaning is that the scalar is added or subtracted to each element. (This is not standard mathematical notation; in VMLS we denote this as, e.g., $x+a1$, where $x$ is an n-vector and $a$ is a scalar.) In Julia you can also carry out scalar-vector addition with the scalar on the left."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       " -0.2999999999999998\n",
       " -5.1               \n",
       " -1.0999999999999999"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[1.1, -3.7, 0.3] .- 1.4 #Vector-scalar subtraction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       "  1.7                \n",
       " -0.30000000000000004"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.7 .+ [1, -1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Elementwise operations.** Julia supports methods for carrying out an operation on every element or coefficient of a vector. To do this we add a period or dot before the operator. For example, if x and y are vectors of the same length, then ```x.*y, x./y, x.\\y, x.^y``` are elementwise vector-vector operations. They result in vectors of the same length as x and y, and $i$th element $x_iy_, x_i/y_i, y_i/x_i$, and $x^y_i$, respectively.\n",
    "\n",
    "As an example of elementwise division, let's find the 3-vector of asset returns ```r``` from the (vectors of) initial and final prices of assets (see page 22 in VMLS)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       "  0.04063205417607233 \n",
       " -0.02239140170174653 \n",
       "  0.006165228113440097"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p_initial = [ 22.15, 89.32, 56.77 ];\n",
    "p_final = [ 23.05, 87.32, 57.12 ];\n",
    "r = (p_final - p_initial) ./ p_initial"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Elementwise operations with a scalar.** Elementwise operations work when one of the arguments is a scalar, in which case it is interpreted as the scalar times a ones vector of the appropriate dimension. Scalar-vector addition, described above, is a special case of this. If ```a``` is a scalar and ```x``` is a vector then ```x.^a``` is a vector with ith element $x^a_i$, and ```a.^x``` is a vector with elements $a^{xi}$. Like scalar-vector addition, the dot notation for elementwise operations is not standard mathematical notation and we do not use it in VMLS. \n",
    "\n",
    "We can also use the period notation with a function that has a name, to let Julia know that the function should be applied elementwise. In this case we add the period *after* the function name to indicate that it should be applied elementwise. For example, if ```x``` is a vector, we can form ```sin.(x)``` to apply the $sine$ function to each element of ```x```.\n",
    "\n",
    "The equality test operator ```==``` (and other relational operators like ```<```,```>=```) can be made to work elementwise by preceding it with a period: ```x == y``` tells us whether or not ```x``` and ```y``` are the same vector; ```x.==y``` is a vector whose entries tell us whether the corresponding entries in ```x``` and ```y``` are the same. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element BitArray{1}:\n",
       "  true\n",
       "  true\n",
       " false"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w = [1,2,2]; z = [1,2,3]\n",
    "w == z\n",
    "w .== z"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can combine this with Julia's slicing to extract the subvector of entries that satisfy some logical condition. For example ```x[abs.(x).>1]``` gives the subvector of ```x``` consisting of the entries larger than one in magnitude. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       "  1.1\n",
       "  0.5\n",
       " -1.5\n",
       " -0.3"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [1.1, .5, -1.5, -0.3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       "  1.1\n",
       " -1.5"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[abs.(x) .> 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dot notation works with assignment too, allowing you to assign multiple entries of a vector to a scalar value. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " 0.39536010417703293\n",
       " 0.48934731813070886\n",
       " 0.44229624376178056\n",
       " 0.29862833289197144"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = rand(4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.0                \n",
       "  1.0                \n",
       "  0.44229624376178056\n",
       "  0.29862833289197144"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[1:2] = [-1, 1]\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " -1.0                \n",
       "  1.3                \n",
       "  1.3                \n",
       "  0.29862833289197144"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[2:3] .= 1.3\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Linear combination.** You can form a linear combination in Julia using scalar-vector multiplication and addition."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       " 4.0\n",
       " 5.0"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [1, 2]; b = [ 3, 4]\n",
    "alpha = -0.5; beta = 1.5;\n",
    "c = alpha*a + beta*b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To illustrate some additional Julia syntax, we create a function that takes a list of coefficients and a list of vectors as its arguments, and returns the linear combination. The lists can be represented by tuples or arrays. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "lincomb (generic function with 1 method)"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function lincomb(coeff,vectors)\n",
    "    n = length(vectors[1]) # Length of vectors\n",
    "    a = zeros(n)\n",
    "    for i = 1:length(vectors)\n",
    "        a = a + coeff[i] * vectors[i];\n",
    "    end\n",
    "    return a\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       " 4.0\n",
       " 5.0"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lincomb((-0.5,1.5), ([1,2], [3,4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A more concise definition of the function is as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2-element Array{Float64,1}:\n",
       " 4.0\n",
       " 5.0"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function lincomb(coeff,vectors)\n",
    "    return sum(coeff[i] * vectors[i] for i = 1:length(vectors))\n",
    "end\n",
    "lincomb((-0.5,1.5), ([1,2], [3,4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Checking properties.** Let's check the distributive property\n",
    "$$\\beta(a+b) = \\beta a+\\beta b,$$\n",
    "which holds for any two n-vectors $a$ and $b$, and any scalar $\\beta$. We'll do this for $n=3$, and randomly generated $a$, $b$, and $\\beta$. (This computation does not show that the property always holds; it only shows that it holds for the specific vectors chosen. But it's good to be skeptical and check identities with random arguments.) We use the ```lincomb``` function we just defined. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([0.74617, 0.156966, 0.991444], [0.907603, 0.668654, 0.611658], 1.1631489234543737)"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = rand(3)\n",
    "b = rand(3)\n",
    "beta = randn()\n",
    "a,b,beta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       " 1.9235839548968818\n",
       " 0.9603199223492835\n",
       " 1.864646441522345 "
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lhs = beta*(a+b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       " 1.9235839548968818\n",
       " 0.9603199223492835\n",
       " 1.864646441522345 "
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rhs = beta*a + beta * b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Although the two vectors lhs and rhs are displayed as the same, they might not be exactly the same, due to very small round-off errors in floating point computations. When we check an identity using random numbers, we can expect that the left-hand and right-hand sides of the identity are not exactly the same, but very close to each other."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.4 Inner product"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Inner product. The inner product of n-vectors $x$ and $y$ is denoted as $x^Ty$. In Julia, the inner product of ```x``` and ```y``` is denoted as ```x'*y```."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-7"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [-1,2,2];\n",
    "y = [1, 0, -3];\n",
    "x'*y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Net present value. As an example, the following code snippet finds the net present value (NPV) of a cash flow vector $c$, with per-period interest rate $r$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4-element Array{Float64,1}:\n",
       " 1.0               \n",
       " 0.9523809523809523\n",
       " 0.9070294784580498\n",
       " 0.863837598531476 "
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = [0.1,0.1,0.1,1.1]; #Cash flow vector\n",
    "n = length(c)\n",
    "r = 0.05; #5% per-period interest rate\n",
    "d = (1+r) .^ - (0:n-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.236162401468524"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "NPV = c'*d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the fourth line, to get the vector ```d``` we raise the scalar ```1+r``` elementwise to the powers given in the array ```(0:n-1)```, which expands to ```[0,1,...,n-1]```.\n",
    "\n",
    "**Total school-age population.** Suppose that the 100-vector ``x`` gives the age distribution of some population, with $x_i$ the number of people of age ```i-1```, for $i = 1,...100$. The total number of people with age between 5 and 18 (inclusive) is given by $x_6+x_7+...+x_{18}+x_{19}$. We can express this as $s^Tx$, where $s$ is the vector with entries for ```i = 6,...,19``` and zero otherwise. In Julia, this is expressed as"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "161.0"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = [zeros(5); ones(14); zeros(81)]\n",
    "x_ages = [rand(5:18) for i = 1:100]\n",
    "school_age_pop = s'*x_ages"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Several other expressions can be used to evaluate this quantity, for example, the expression ```sum(x[6:19])```, using the Julia function ```sum```, which gives the sum of the entries of a vector. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.5 Complexity of vector computations\n",
    "**Floating point operators**. For any two numbers $a$ and $b$, we have $(a+b)(a-b) = a^2-b^2$. When a computer calculates the left-hand and right-hand side, for specific numbers $a$ and $b$, they need not be exactly the same, due to very small floating point roud-off errors. But they should be very nearly the same. Let's see an example of this. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.25488033497122203"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = rand();b = rand();\n",
    "lhs = (a+b) * (a-b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.2548803349712221"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rhs = a^2 - b^2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5.551115123125783e-17"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lhs-rhs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we see that the left-hand and right-hand sides are not exactly equal, but very close. [in this case they're equal but if we increased precision by ~2 decimal places we would see slight inequality]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Complexity**. You can time a Julia command by adding ```@time``` before the command. The timer is not very accurate for very small times, say, measured in microseconds $(10^{-6} seconds)$. Also, you should run the command more than once; it can be a lot faster on the second of subsequent runs. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.000080 seconds (6 allocations: 192 bytes)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-177.72967596013314"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = randn(10^5); b = randn(10^5)\n",
    "@time a'*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.000098 seconds (6 allocations: 192 bytes)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-177.72967596013314"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time a'*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.000742 seconds (6 allocations: 192 bytes)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-667.0301195473043"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = randn(10^6); d = randn(10^6)\n",
    "@time c'*d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.000685 seconds (6 allocations: 192 bytes)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-667.0301195473043"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time c'*d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first inner product, of a vector of length $10^5$, takes around $0.00017$ seconds; the second, with vectors of length $10^6$ (ten times bigger), product takes around $0.0018$ seconds, about $10$ longer. This is predicted by complexity of the inner product, which is $2n-1$ flops. The computer on which the computations were done is capable of around $2\\times10^6/0.001765$ flops per second, i.e., around $1$ Gflop/s. These timings, and the estimate of the computer speed, are very approximate. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Sparse vectors**. Functions for creating and manipulating sparse vectors are contained in the Julia package SparseArrays, so you need to install this package before you can use them; see page ix [in .pdf companion]."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Spare vectors are stored as sparse arrays, i.e., arrays in which only the nonzero elements are stored. In Julia you can create a sparse vector from lists of the indices and values using the ```sparsevec``` function. You can also first create a sparse vector of zeros (using ```spzeros(n)```) and then assign values to the nonzero entries. A sparse vector can be created from a non-sparse vector using ```sparse(x)```, which returns a sparse version of ```x```. ```nnz(x)``` gives the number of nonzero elmeents of a sparse vector. Sparse vectors are overloaded to work as you imagine; for example, all the usual vector operations work, and they are automatically recast as non-sparse vectors when appropriate. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "using SparseArrays #Please refer to installation instructions in the .pdf companion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1000000-element SparseVector{Float64,Int64} with 2 stored entries:\n",
       "  [123456 ]  =  1.0\n",
       "  [123457 ]  =  -1.0"
      ]
     },
     "execution_count": 91,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = sparsevec([123456, 123457],[1.0,-1.0], 10^6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1000000"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "length(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nnz(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.086005 seconds (202.88 k allocations: 10.190 MiB, 9.32% gc time)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "1000000-element SparseVector{Float64,Int64} with 2 stored entries:\n",
       "  [123456 ]  =  2.0\n",
       "  [123457 ]  =  -2.0"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = randn(10^6) #An ordinary (non-sparse vector)\n",
    "@time 2*a #Computed efficiently!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.008577 seconds (29 allocations: 7.631 MiB)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "1000000-element Array{Float64,1}:\n",
       " -4.029344569473563  \n",
       " -1.5368258300865218 \n",
       "  0.40383751493017805\n",
       " -1.618216935777686  \n",
       "  4.18473585098803   \n",
       " -4.3902927873295585 \n",
       " -0.7220643692827817 \n",
       "  1.0236851395169786 \n",
       "  2.9453829140331895 \n",
       " -0.3617769660889115 \n",
       "  0.9229190658411318 \n",
       "  0.7372583372625133 \n",
       "  1.5163935914001956 \n",
       "  ⋮                  \n",
       " -4.405085582058751  \n",
       " -5.004388876363208  \n",
       "  1.420247136405523  \n",
       "  0.46381876784284637\n",
       " -0.795396051519772  \n",
       " -0.34005852500511785\n",
       " -0.7287349341317629 \n",
       " -3.1223132116063606 \n",
       "  2.0308112343757116 \n",
       "  0.0911687445194015 \n",
       " -5.354134246617548  \n",
       " -1.4638764464312213 "
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time 2*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.019590 seconds (42.15 k allocations: 2.239 MiB)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-0.4151762985250746"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time a'*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.000427 seconds (6 allocations: 192 bytes)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "999562.8684827174"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time b'*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.301939 seconds (438.84 k allocations: 52.472 MiB, 5.15% gc time)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "1000000-element SparseVector{Float64,Int64} with 1000000 stored entries:\n",
       "  [1      ]  =  -2.01467\n",
       "  [2      ]  =  -0.768413\n",
       "  [3      ]  =  0.201919\n",
       "  [4      ]  =  -0.809108\n",
       "  [5      ]  =  2.09237\n",
       "  [6      ]  =  -2.19515\n",
       "  [7      ]  =  -0.361032\n",
       "  [8      ]  =  0.511843\n",
       "  [9      ]  =  1.47269\n",
       "  [10     ]  =  -0.180888\n",
       "             ⋮\n",
       "  [999990 ]  =  -2.50219\n",
       "  [999991 ]  =  0.710124\n",
       "  [999992 ]  =  0.231909\n",
       "  [999993 ]  =  -0.397698\n",
       "  [999994 ]  =  -0.170029\n",
       "  [999995 ]  =  -0.364367\n",
       "  [999996 ]  =  -1.56116\n",
       "  [999997 ]  =  1.01541\n",
       "  [999998 ]  =  0.0455844\n",
       "  [999999 ]  =  -2.67707\n",
       "  [1000000]  =  -0.731938"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time c = a + b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the last line, the sparse vector a is automatically converted to an ordinary vector (array) so it can be added to the random vector; the result is a (non-sparse) vector of length $10^6$. "
   ]
  }
 ],
 "metadata": {
  "@webio": {
   "lastCommId": null,
   "lastKernelId": null
  },
  "kernelspec": {
   "display_name": "Julia 1.1.1",
   "language": "julia",
   "name": "julia-1.1"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.1.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
